/**
 * 单例模式基类和工具
 * 
 * 提供三种单例模式实现：
 * 1. 懒加载单例（推荐）- 延迟初始化，节省内存
 * 2. 立即加载单例 - 启动时初始化，确保可用性
 * 3. 线程安全单例 - 支持异步初始化
 * 
 * @author AI Assistant
 * @date 2025-11-27
 */

import { Log } from '../logger/LoggerGlobal';

/**
 * 单例接口
 */
export interface ISingleton {
    /** 销毁单例实例 */
    destroy?(): void;
}

/**
 * 单例选项
 */
export interface SingletonOptions {
    /** 是否启用日志 */
    enableLog?: boolean;
    /** 是否在销毁时重置实例 */
    autoReset?: boolean;
}

/**
 * 懒加载单例基类（推荐）
 * 
 * 特点：
 * - 延迟初始化，首次访问时创建
 * - 节省内存和启动时间
 * - 支持重置和销毁
 * 
 * 使用示例：
 * ```typescript
 * export class MyManager extends LazySingleton<MyManager> {
 *     private data: string = '';
 *     
 *     protected constructor() {
 *         super();
 *         // 初始化代码
 *     }
 * }
 * 
 * // 使用
 * const manager = MyManager.getInstance();
 * ```
 */
export abstract class LazySingleton<T> implements ISingleton {
    private static instances: Map<string, any> = new Map();
    private static options: SingletonOptions = {
        enableLog: false,
        autoReset: true
    };
    
    /**
     * 构造函数必须是 protected，防止外部直接 new
     */
    protected constructor() {}
    
    /**
     * 获取单例实例
     */
    static getInstance<T extends LazySingleton<any>>(this: { new (): T }): T {
        const className = this.name;
        
        if (!LazySingleton.instances.has(className)) {
            if (LazySingleton.options.enableLog) {
                Log.general.debug('创建单例实例', { className });
            }
            
            const instance = new (this as any)();
            LazySingleton.instances.set(className, instance);
        }
        
        return LazySingleton.instances.get(className) as T;
    }
    
    /**
     * 重置单例实例（用于测试或重新初始化）
     */
    static resetInstance<T extends LazySingleton<any>>(this: { new (): T }): void {
        const className = this.name;
        const instance = LazySingleton.instances.get(className);
        
        if (instance) {
            if (LazySingleton.options.enableLog) {
                Log.general.debug('重置单例实例', { className });
            }
            
            // 调用 destroy 方法（如果存在）
            if (typeof instance.destroy === 'function') {
                instance.destroy();
            }
            
            LazySingleton.instances.delete(className);
        }
    }
    
    /**
     * 检查实例是否已创建
     */
    static hasInstance<T extends LazySingleton<any>>(this: { new (): T }): boolean {
        return LazySingleton.instances.has(this.name);
    }
    
    /**
     * 配置单例选项
     */
    static configure(options: Partial<SingletonOptions>): void {
        LazySingleton.options = { ...LazySingleton.options, ...options };
    }
    
    /**
     * 销毁方法（子类可覆盖）
     */
    destroy?(): void {
        // 子类实现具体的销毁逻辑
    }
}

/**
 * 立即加载单例装饰器
 * 
 * 特点：
 * - 类加载时立即创建实例
 * - 确保实例始终可用
 * - 适用于必须的核心系统
 * 
 * 使用示例：
 * ```typescript
 * @EagerSingleton()
 * export class CoreManager {
 *     private static instance: CoreManager;
 *     
 *     private constructor() {}
 *     
 *     static getInstance(): CoreManager {
 *         return CoreManager.instance;
 *     }
 * }
 * ```
 */
export function EagerSingleton() {
    return function <T extends { new (...args: any[]): any }>(constructor: T) {
        return class extends constructor {
            private static _instance: any = new constructor();
            
            constructor(...args: any[]) {
                super(...args);
                return (constructor as any)._instance;
            }
            
            static getInstance(): any {
                return (constructor as any)._instance;
            }
        };
    };
}

/**
 * 异步单例基类
 * 
 * 特点：
 * - 支持异步初始化
 * - 线程安全（Promise 保证）
 * - 适用于需要异步资源的系统
 * 
 * 使用示例：
 * ```typescript
 * export class AssetManager extends AsyncSingleton<AssetManager> {
 *     protected async init(): Promise<void> {
 *         // 异步初始化代码
 *         await this.loadAssets();
 *     }
 * }
 * 
 * // 使用
 * const manager = await AssetManager.getInstance();
 * ```
 */
export abstract class AsyncSingleton<T> implements ISingleton {
    private static instances: Map<string, Promise<any>> = new Map();
    private static options: SingletonOptions = {
        enableLog: false,
        autoReset: true
    };
    
    /** 是否已初始化 */
    protected _initialized: boolean = false;
    
    /**
     * 构造函数必须是 protected
     */
    protected constructor() {}
    
    /**
     * 异步初始化方法（子类必须实现）
     */
    protected abstract init(): Promise<void>;
    
    /**
     * 获取单例实例（异步）
     */
    static async getInstance<T extends AsyncSingleton<any>>(
        this: { new (): T }
    ): Promise<T> {
        const className = this.name;
        
        if (!AsyncSingleton.instances.has(className)) {
            if (AsyncSingleton.options.enableLog) {
                Log.general.debug('创建异步单例实例', { className });
            }
            
            const initPromise = (async () => {
                const instance = new (this as any)();
                await instance.init();
                instance._initialized = true;
                return instance;
            })();
            
            AsyncSingleton.instances.set(className, initPromise);
        }
        
        return AsyncSingleton.instances.get(className) as Promise<T>;
    }
    
    /**
     * 重置单例实例
     */
    static async resetInstance<T extends AsyncSingleton<any>>(
        this: { new (): T }
    ): Promise<void> {
        const className = this.name;
        const instancePromise = AsyncSingleton.instances.get(className);
        
        if (instancePromise) {
            if (AsyncSingleton.options.enableLog) {
                Log.general.debug('重置异步单例实例', { className });
            }
            
            const instance = await instancePromise;
            
            if (typeof instance.destroy === 'function') {
                await instance.destroy();
            }
            
            AsyncSingleton.instances.delete(className);
        }
    }
    
    /**
     * 检查实例是否已创建
     */
    static hasInstance<T extends AsyncSingleton<any>>(this: { new (): T }): boolean {
        return AsyncSingleton.instances.has(this.name);
    }
    
    /**
     * 配置单例选项
     */
    static configure(options: Partial<SingletonOptions>): void {
        AsyncSingleton.options = { ...AsyncSingleton.options, ...options };
    }
    
    /**
     * 销毁方法（子类可覆盖）
     */
    destroy?(): void | Promise<void> {
        // 子类实现具体的销毁逻辑
    }
}

/**
 * 单例管理器
 * 
 * 统一管理所有单例实例，提供：
 * - 全局销毁
 * - 统计信息
 * - 批量重置
 */
export class SingletonManager {
    private static singletons: Map<string, ISingleton> = new Map();
    
    /**
     * 注册单例
     */
    static register(name: string, instance: ISingleton): void {
        this.singletons.set(name, instance);
        Log.general.debug('注册单例', { name });
    }
    
    /**
     * 注销单例
     */
    static unregister(name: string): void {
        const instance = this.singletons.get(name);
        if (instance && typeof instance.destroy === 'function') {
            instance.destroy();
        }
        this.singletons.delete(name);
        Log.general.debug('注销单例', { name });
    }
    
    /**
     * 获取单例
     */
    static get(name: string): ISingleton | undefined {
        return this.singletons.get(name);
    }
    
    /**
     * 销毁所有单例
     */
    static destroyAll(): void {
        Log.general.info('销毁所有单例', {
            count: this.singletons.size
        });
        
        for (const [name, instance] of this.singletons) {
            if (typeof instance.destroy === 'function') {
                instance.destroy();
            }
        }
        
        this.singletons.clear();
    }
    
    /**
     * 获取统计信息
     */
    static getStatistics() {
        return {
            totalSingletons: this.singletons.size,
            singletonNames: Array.from(this.singletons.keys())
        };
    }
    
    /**
     * 打印统计信息
     */
    static printStatistics(): void {
        const stats = this.getStatistics();
        
        Log.styled('━'.repeat(60), 'separator');
        Log.styled('📊 单例管理器统计', 'title');
        Log.styled('━'.repeat(60), 'separator');
        
        Log.general.info(`单例总数: ${stats.totalSingletons}`);
        
        if (stats.singletonNames.length > 0) {
            Log.styled('📋 已注册的单例', 'large');
            for (const name of stats.singletonNames) {
                Log.general.info(`  - ${name}`);
            }
        }
        
        Log.styled('━'.repeat(60), 'separator');
    }
}

/**
 * 使用示例
 * 
 * 1. 懒加载单例（推荐）：
 * ```typescript
 * export class MyManager extends LazySingleton<MyManager> {
 *     protected constructor() {
 *         super();
 *     }
 * }
 * const manager = MyManager.getInstance();
 * ```
 * 
 * 2. 异步单例：
 * ```typescript
 * export class AssetManager extends AsyncSingleton<AssetManager> {
 *     protected async init(): Promise<void> {
 *         await this.loadAssets();
 *     }
 * }
 * const manager = await AssetManager.getInstance();
 * ```
 * 
 * 3. 直接导出实例（简单场景）：
 * ```typescript
 * class MyManager extends LazySingleton<MyManager> {
 *     protected constructor() {
 *         super();
 *     }
 * }
 * export const myManager = MyManager.getInstance();
 * ```
 */

